﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using ActiveDs;
using System.Web.Script.Serialization;
using System.Data;
using System.IO;
using System.Data.SqlClient;
using System.Web;
using System.Reflection;
using System.Collections;

namespace ViVa.ActiveDirectory
{
    public class Helper
    {
        public static object GetValueFromDirectoryEntry(DirectoryEntry entry, string property)
        {
            var collection = entry.Properties[property];
            if (collection != null)
            {
                return collection.Value;
            }
            return null;
        }

        public static void SetValueFromDirectoryEntry(DirectoryEntry entry, string property, object value)
        {
            var collection = entry.Properties[property];
            if (collection != null)
            {
                collection.Value = value;
            }
        }
        
        public static DateTime GetDateTimeFromString(string datetimeString)
        {
            return DateTime.ParseExact(datetimeString, "dd-MM-yyyy HH:mm:ss", null);
        }

        public static string GetStringFromDateTime(DateTime dateTime)
        {
            return dateTime.ToString("dd-MM-yyyy");
        }

        public static DateTime GetDateTimeFromLargeInteger(IADsLargeInteger largeIntValue)
        {
            //
            // Convert large integer to int64 value
            //
            long int64Value = (long)((uint)largeIntValue.LowPart +
                     (((long)largeIntValue.HighPart) << 32));
            
            //
            // Return the DateTime in utc
            //
            return DateTime.FromFileTimeUtc(int64Value);
        }

        public static IADsLargeInteger GetLargeIntegerFromDateTime(DateTime dateTimeValue)
        {
            // 
            // Convert DateTime value to utc file time
            //
            Int64 int64Value = dateTimeValue.ToFileTimeUtc();
            
            //
            // convert to large integer
            //
            IADsLargeInteger largeIntValue = 
                (IADsLargeInteger) new LargeInteger();
            largeIntValue.HighPart = (int) (int64Value >> 32);
            largeIntValue.LowPart = (int) (int64Value & 0xFFFFFFFF);

            return largeIntValue;
        }




        
        public static string ToJson(object o)
        {
            JavaScriptSerializer Serializer = new JavaScriptSerializer();
            string ser = Serializer.Serialize(o);
            return ser;
        }


        public static ADEntry JsonToADEntry(string s)
        {
            JavaScriptSerializer Serializer = new JavaScriptSerializer();
            return Serializer.Deserialize<ADEntry>(s);
        }

        public static DataSet ToDataSet<T>(IList<T> list)
        {
            Type elementType = typeof(T);
            DataSet ds = new DataSet();
            DataTable t = new DataTable();
            ds.Tables.Add(t);

            //add a column to table for each public property on T
            foreach (var propInfo in elementType.GetProperties())
            {
                Type ColType = Nullable.GetUnderlyingType(propInfo.PropertyType) ?? propInfo.PropertyType;

                t.Columns.Add(propInfo.Name, ColType);
            }

            //go through each property on T and add each value to the table
            foreach (T item in list)
            {
                DataRow row = t.NewRow();

                foreach (var propInfo in elementType.GetProperties())
                {
                    row[propInfo.Name] = propInfo.GetValue(item, null) ?? DBNull.Value;
                }

                t.Rows.Add(row);
            }

            return ds;
        }


        public static string CsvToJson(string value)
        {
            // Get lines.
            if (value == null) return null;
            string[] lines = value.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            if (lines.Length < 2) throw new InvalidDataException("Must have header line.");

            // Get headers.
            string[] headers = lines.First().Split(',');
            // Build JSON array.
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("[");
            for (int i = 1; i < lines.Length; i++)
            {
                string[] fields = lines[i].Split(',');
                if (fields.Length != headers.Length) throw new InvalidDataException("Field count must match header count.");
                var jsonElements = headers.Zip(fields, (header, field) => string.Format("{0}: {1}", header, field)).ToArray();
                string jsonObject = "{" + string.Format("{0}", string.Join(",", jsonElements)) + "}";
                if (i < lines.Length - 1)
                    jsonObject += ",";
                sb.AppendLine(jsonObject);
            }
            sb.AppendLine("]");
            return sb.ToString();
        }


        public static DataTable ConvertSqlDataReaderToDataTable(SqlDataReader myReader)
        {
            DataTable dtYoYo = new DataTable();
            bool constructedDataTable = false;

            string ColName;
            while (myReader.Read())
            {
                if (constructedDataTable == false)
                {
                    for (Int32 i = 0; i < myReader.FieldCount; i++)
                    {
                        ColName = myReader.GetName(i).ToString();
                        dtYoYo.Columns.Add(ColName);
                    }
                    constructedDataTable = true;
                }
                DataRow row = dtYoYo.NewRow();
                for (Int32 i = 0; i < myReader.FieldCount; i++)
                {
                    ColName = myReader.GetName(i).ToString();
                    row[ColName] = myReader[ColName];
                }
                dtYoYo.Rows.Add(row);
            }
            return dtYoYo;
        }
    }
}